package com.andaily.service.impl;

import com.andaily.domain.cooking.CookingAccount;
import com.andaily.domain.cooking.CookingAccountRepository;
import com.andaily.domain.cooking.CookingAccountStatus;
import com.andaily.domain.cooking.settlement.CookingSettlement;
import com.andaily.domain.cooking.settlement.CookingSettlementGenerator;
import com.andaily.domain.dto.cooking.CookingAccountDto;
import com.andaily.domain.dto.cooking.CookingSettlementDto;
import com.andaily.domain.dto.cooking.CookingSettlementHistoryDto;
import com.andaily.domain.dto.cooking.SettlementFormDto;
import com.andaily.domain.shared.paginated.PaginatedLoader;
import com.andaily.infrastructure.support.LogHelper;
import com.andaily.service.SettlementService;
import org.springframework.beans.factory.annotation.Autowired;

import java.math.BigDecimal;
import java.text.MessageFormat;
import java.util.List;

/**
 * @author Shengzhao Li
 */
public class SettlementServiceImpl implements SettlementService {

    private static LogHelper log = LogHelper.create(SettlementServiceImpl.class);

    @Autowired
    private CookingAccountRepository cookingAccountRepository;

    @Override
    public SettlementFormDto loadSettlementForm() {
        BigDecimal recordedAmount = cookingAccountRepository.amountOfCookingAccountByStatus(CookingAccountStatus.RECORDED);
        log.debug(MessageFormat.format("Current available settlement accounts total amount: {0}", recordedAmount));
        SettlementFormDto dto = new SettlementFormDto();
        dto.updateAmount(recordedAmount);

        List<CookingAccount> accountList = cookingAccountRepository.findCookingAccountsByStatus(CookingAccountStatus.RECORDED);
        dto.setAccounts(CookingAccountDto.toDtos(accountList));
        return dto;
    }

    @Override
    public String submitSettlement(SettlementFormDto settlementFormDto) {
        CookingSettlementGenerator generator = new CookingSettlementGenerator(settlementFormDto.getAccountGuids());
        CookingSettlement settlement = generator.generate();
        settlement.save();
        return settlement.guid();
    }

    @Override
    public CookingSettlementDto loadCookingSettlement(String guid) {
        CookingSettlement settlement = cookingAccountRepository.findSettlementByGuid(guid);
        return new CookingSettlementDto(settlement);
    }

    @Override
    public CookingSettlementDto loadRealTimeCookingSettlement() {
        List<String> accountGuids = cookingAccountRepository.findAllRecordedCookingAccounts();
        CookingSettlementGenerator generator = new CookingSettlementGenerator(accountGuids.toArray(new String[accountGuids.size()]));
        CookingSettlement settlement = generator.setUpdateStatus(false).generate();
        return new CookingSettlementDto(settlement);
    }

    @Override
    public CookingSettlementHistoryDto loadCookingSettlementHistory(final CookingSettlementHistoryDto overviewDto) {
        BigDecimal totalAmount = cookingAccountRepository.totalAmountOfSettlements();
        int totalAccountSize = cookingAccountRepository.totalSettlementAccountSize();
        overviewDto.update(totalAmount, totalAccountSize);

        return overviewDto.load(new PaginatedLoader<CookingSettlementDto>() {
            @Override
            public List<CookingSettlementDto> loadList() {
                List<CookingSettlement> settlements = cookingAccountRepository.findCookingSettlements(overviewDto);
                return CookingSettlementDto.toDtos(settlements);
            }

            @Override
            public int loadTotalSize() {
                return cookingAccountRepository.totalCookingSettlements(overviewDto);
            }
        });
    }
}
